#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>

#include <unistd.h>

#include "MurmurHash3.h"
#include "cache.h"
#include "list.h"
#include "pthreadpool.h"

#define BUFLEN 512

void free_value(void *key)
{

	if (key != NULL)
		free((char *)key);

	return;
}

int main(int argc, char **argv)
{
	/* Length of the password */
	unsigned short int length = 8;
	int dumpLen;

	char *sbuf, *ptr;
	char **kbuf;

	int opt, minc, maxc;
	int ttl, err;
	int i;

	minc = 8;
	maxc = 64;
	ttl = 100;

	if (argc < 2) {
		printf("usage: %s -n num_of_str -m min_str_len -x max_str_len -t ttl\n", argv[0]);
		exit(-1);
	}

	while ((opt = getopt(argc, argv, "m:n:x:t:")) != -1) {
		switch (opt) {
		case 'm':
			minc = atol(optarg);
			break;
		case 'x':
			maxc = atol(optarg);
			if (maxc > BUFLEN)
				maxc = BUFLEN;
			break;
		case 'n':
			dumpLen = atoi(optarg);
			break;
		case 't':
			ttl = atoi(optarg);
			break;
		default:
			break;
		}
	}

	/* Seed number for rand() */
	srand((unsigned int)time(0) + getpid());

	ll_cache_t *cache;
	/* ASCII characters 33 to 126 */

	if (!(cache = ll_cache_create(4096, 0, &err))) {
		fprintf(stderr, "%s: ll_cache_create: %s\n", argv[0], strerror(err));
		exit(EXIT_FAILURE);
	}
	cache->compare_func = NULL;
	cache->destroy_func = free_value;
	cache->size_func = NULL;
	cache->xchain_func = NULL;
	cache->mtime = time(NULL);

	kbuf = calloc(dumpLen, sizeof(char *));

	for (i = 0L; i < dumpLen; i++) {
		kbuf[i] = calloc(maxc + 1, sizeof(char));
		length = (int)(rand() % maxc + minc);
		sprintf(kbuf[i], "key%04d", randi(length * 1024));
		sbuf = (char *)calloc(maxc + 16, sizeof(char));

		while (length--)
			sbuf[length] = (char)(rand() % 75 + 48);
		//   srand(rand());
		fprintf(stderr, "SET %12s : %s\n", kbuf[i], sbuf);

		if (ll_cache_set(cache, kbuf[i], (void *)sbuf, LL_CACHE_FLAG_DONT_FREE, &err) < 0) {
			fprintf(stderr, "cache_set_error %s\n", sbuf);
			exit(0);
		}
	}

	for (i = 0L; i < dumpLen; i++) {
		ptr = NULL;

		if (!(ptr = (char *)ll_cache_get(cache, kbuf[i], 0, &err)) && err) {
			;;
		}

		if (ptr) {
			fprintf(stderr, "GET %12s : %s\n", kbuf[i], ptr);
			if (ll_cache_unset(cache, kbuf[i], 0, &err) < 0) {
				fprintf(stderr, "unset error %s\n", kbuf[i]);
			}
		}

	}

	ll_cache_destroy(cache, 0, &err);
	return EXIT_SUCCESS;
}
